﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.UI.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace CPPEI.Coolzon.Designer.Views
{
    /// <summary>
    /// 选中一个组件实例的委托
    /// </summary>
    /// <param name="partInstance"></param>
    public delegate void SelectedChangedEventHandler(Coolzon.UI.Part partInstance);

    /// <summary>
    /// 组件被创建的事件
    /// </summary>
    /// <param name="newPart"></param>
    public delegate void AddedEventHandler(Coolzon.UI.Part part);

    /// <summary>
    /// 组件被删除的事件
    /// </summary>
    /// <param name="part"></param>
    public delegate void RemovedEventHandler(Coolzon.UI.Part part);

    /// <summary>
    /// 场景事件
    /// </summary>
    /// <param name="scene"></param>
    public delegate void SceneEventHandler(Coolzon.UI.ScenePart scene);

    /// <summary>
    /// 场景修改事件
    /// </summary>
    public delegate void SceneDirtiedEvent();

    public partial class DesignView
    {
        /// <summary>
        /// 选中的组件变事件
        /// </summary>
        public event SelectedChangedEventHandler SelectedChanged;
        public event AddedEventHandler Added;
        public event RemovedEventHandler Removed;
        /// <summary>
        /// 场景打开事件
        /// </summary>
        public event SceneEventHandler Opened;
        public event SceneEventHandler Closed;
        public event SceneDirtiedEvent Dirtied;

        public Coolzon.UI.Part ToPastePart { get; private set; }
        public PasteType PasteType { get; set; }

        private long _pasteCount = 1;

        /// <summary>
        /// 当前的方案
        /// </summary>
        public Coolzon.Designtime.Metadata.Solution Solution { get; set; }

        public Coolzon.Designtime.Metadata.Scene CurrentDesignMetadata4Scene { get; set; }

        /// <summary>
        /// 当前场景
        /// </summary>
        public Coolzon.Metadata.Scene CurrentScene { get; set; }

        /// <summary>
        /// 已选中的组件类型
        /// </summary>
        public Coolzon.Metadata.PartLibItem SelectedPartLibItem { get; set; }

        /// <summary>
        /// 设置方案
        /// </summary>
        /// <param name="solution"></param>
        public void API_SetSolution(Coolzon.Designtime.Metadata.Solution solution)
        {
            this.Dispatcher.Invoke(() =>
            {
                Solution = solution;
                _ctlMainFrame.Init(Solution.RT_Solution);
            });
        }

        /// <summary>
        /// 打开场景
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="isEditable">是否可以编辑,true:可编辑，false：不可编辑</param>
        public void API_OpenScene(string sceneName, bool isEditable)
        {
            Logger.DebugToTag(Library.LogTAG, string.Format("请求打开场景{0}，可编辑:{1}", sceneName, isEditable));

            if (CurrentDesignMetadata4Scene != null && CurrentDesignMetadata4Scene.Name == sceneName)
            {
                Logger.WarningToTag(Library.LogTAG, string.Format("打开场景{0}失败，和当前打开的场景一致", sceneName));
                return;
            }
            _OpenScene(sceneName, isEditable);
            Event.UI.UIEventBus.Publish(new Event.UI.UIToolboxSelectPointerEvent());
        }
        /// <summary>
        /// 重新打开当前方案,在修改场景属性时使用
        /// </summary>
        public void API_ReOpenScene()
        {
            Logger.DebugToTag(Library.LogTAG, string.Format("请求打开场景{0}，可编辑:{1}", CurrentDesignMetadata4Scene.Name, _isEditable));
            if (CurrentDesignMetadata4Scene != null)
            {
                _OpenScene(CurrentDesignMetadata4Scene.Name, _isEditable);
                if (this.SelectedChanged != null)
                {
                    this.SelectedChanged(_ctlMainFrame.CurrentScene);
                }
                this._selectedPart = _ctlMainFrame.CurrentScene;
                if (this._selectedPart != null)
                {
                    //更新mask的位置
                    ShowDesignBorder(_selectedPart, _ctlCanvas);

                    //保存设计边框的当前位置大小信息
                    this._dbPosStore = this._ctlDesignBorder.GetOffset();
                    this._dbSizeStore = this._ctlDesignBorder.GetSize();
                }
            }
            Event.UI.UIEventBus.Publish(new Event.UI.UIToolboxSelectPointerEvent());
        }


        /// <summary>
        /// 设置场景的可编辑状态
        /// </summary>
        /// <param name="sceneName"></param>
        /// <param name="isEditable"></param>
        public void API_ChangeEditable(string sceneName, bool isEditable)
        {
            Dispatcher.Invoke(() =>
            {
                Event.UI.UIEventBus.Publish(new Event.UI.UIToolboxSelectPointerEvent());
                if (_ctlMainFrame.CurrentScene != null && _ctlMainFrame.CurrentScene.Name == sceneName)
                {
                    Logger.DebugToTag(Library.LogTAG, string.Format("设置场景{0}的可编辑状态为:{1}成功", sceneName, isEditable));
                    this._isEditable = isEditable;
                    if (!_isEditable)
                    {
                        API_DrawPart(null);
                    }
                }
                else
                {
                    Logger.WarningToTag(Library.LogTAG, string.Format("设置场景{0}的可编辑状态为:{1}失败，和显示的场景不一致", sceneName, isEditable));
                }
            });
        }
        /// <summary>
        /// 场景是否可编辑
        /// </summary>
        /// <returns></returns>
        public bool API_IsEditable()
        {
            return this._isEditable;
        }

        /// <summary>
        /// 开始绘制组件
        /// </summary>
        /// <param name="item"></param>
        public void API_DrawPart(Coolzon.Metadata.PartLibItem item)
        {
            if (item == null)
            {
                // select null partlibitem
                _ShowHLBorder4Part(null);

                //隐藏设计边框
                _ctlDesignBorder.Visibility = System.Windows.Visibility.Hidden;
                #region //取消现在选中的组件
                if (this._selectedPart != null && this.SelectedChanged != null)
                {
                    this.SelectedChanged(null);
                }
                this._selectedPart = null;
                #endregion

                SelectedPartLibItem = item;
                _ctlCanvas.Cursor = Cursors.Arrow;
                _designData.UpdateState(DesignState.Normal);
            }
            else
            {
                _ShowHLBorder4Part(null);

                if (this._isEditable)
                {
                    //隐藏设计边框
                    _ctlDesignBorder.Visibility = System.Windows.Visibility.Hidden;
                    #region //取消现在选中的组件
                    if (this._selectedPart != null && this.SelectedChanged != null)
                    {
                        this.SelectedChanged(null);
                    }
                    this._selectedPart = null;
                    #endregion

                    SelectedPartLibItem = item;

                    _ctlCanvas.Cursor = Cursors.Cross;
                    _designData.UpdateState(DesignState.DrawPart);
                }
            }
        }

        /// <summary>
        /// 选中一个组件,空为选择场景
        /// </summary>
        /// <param name="partName"></param>
        public void API_Select(string partName)
        {
            if (this._ctlMainFrame.CurrentScene == null)
            {
                Logger.ErrorToTag(Library.LogTAG, string.Format("选择组件:{0}失败,CurrentScene为空", partName));
                return;
            }
            Logger.DebugToTag(Library.LogTAG, string.Format("选择组件:{0}", partName));
            Coolzon.UI.Part part = null;
            if (string.IsNullOrWhiteSpace(partName) || string.Equals(partName, CurrentScene.Name))
            {
                part = _ctlMainFrame.CurrentScene;
            }
            else
            {
                part = this._ctlMainFrame.CurrentScene.GetChildPart(partName, true);
            }
            if (part == null)
            {
                Logger.DebugToTag(Library.LogTAG, string.Format("未发现名为:{0}的组件", partName));
            }
            if (this._selectedPart != part)
            {
                this._selectedPart = part;
                if (this.SelectedChanged != null)
                {
                    this.SelectedChanged(this._selectedPart);
                }
                _ctlDesignBorder.Visibility = Visibility.Visible;
                ScrollToSelected(_selectedPart);
            }
        }

        /// <summary>
        /// 复制组件
        /// </summary>
        /// <param name="part"></param>
        public void API_Copy(Coolzon.UI.Part part)
        {
            ToPastePart = part;
            _pasteCount = 1;
            PasteType = PasteType.Copy;
        }
        /// <summary>
        /// 剪切组件
        /// </summary>
        /// <param name="part"></param>
        public void API_Cut(Coolzon.UI.Part part)
        {
            ToPastePart = part;
            _pasteCount = 1;
            PasteType = PasteType.Cut;
        }
        /// <summary>
        /// 取消复制信息，撤销复制时使用
        /// </summary>
        public void API_PasteReset()
        {
            ToPastePart = null;
            PasteType = PasteType.None;
        }

        /// <summary>
        /// 粘贴组件
        /// </summary>
        /// <param name="containerPart"></param>
        public void API_Paste(Coolzon.UI.Part copiedPart, Coolzon.UI.Part pastePart, Coolzon.UI.IPartContainer containerPart, string shortType)
        {
            if (copiedPart == null)
            {
                return;
            }
            if (containerPart == null)
            {
                return;
            }
            //复制时,如果是同一个父容器，则向右下方位移
            if (copiedPart.ParentPart == containerPart)
            {
                _AddPartAndUpdateMetadata(pastePart, containerPart, new System.Windows.Point(copiedPart.XLeft + 15 * _pasteCount, copiedPart.XTop + 15 * _pasteCount++), new System.Windows.Size(copiedPart.XWidth, copiedPart.XHeight), shortType);
            }
            else
            {
                _AddPartAndUpdateMetadata(pastePart, containerPart, new System.Windows.Point(copiedPart.XLeft, copiedPart.XTop), new System.Windows.Size(copiedPart.XWidth, copiedPart.XHeight), shortType);
            }
            // 通知有组件被创建
            _RaiseAddedEvent(pastePart);

            _designData.UpdateState(DesignState.Normal);
            _ctlCanvas.Cursor = Cursors.Arrow;

            if (this.SelectedChanged != null)
            {
                this.SelectedChanged(pastePart);
            }
            _selectedPart = pastePart;

            if (this._selectedPart != null)
            {
                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render,
                 new Action(() =>
                 {
                     //更新mask的位置
                     ShowDesignBorder(_selectedPart, _ctlCanvas);

                     //保存设计边框的当前位置大小信息
                     this._dbPosStore = this._ctlDesignBorder.GetOffset();
                     this._dbSizeStore = this._ctlDesignBorder.GetSize();
                 }));
            }
        }
        /// <summary>
        /// 是否已复制或剪切组件
        /// </summary>
        /// <returns></returns>
        public bool API_HadCopiedOrCuted()
        {
            if (ToPastePart == null)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取当前选择组件
        /// </summary>
        /// <returns></returns>
        public Coolzon.UI.Part API_GetSelectedPart()
        {
            return _selectedPart;
        }
        /// <summary>
        /// 获取当前场景对象
        /// </summary>
        /// <returns></returns>
        public Coolzon.UI.Part API_GetCurrentScenePart()
        {
            return scene;
        }

        /// <summary>
        /// 删除组件
        /// </summary>
        /// <param name="part"></param>
        public void API_Remove(Coolzon.UI.Part part)
        {
            try
            {
                if (part != null)
                {
                    if (part.ParentPart != null)
                    {
                        (part.ParentPart as Coolzon.UI.IPartContainer).XRemovePart(part);
                        if (part.ParentPart is Coolzon.UI.ScenePart)
                        {
                            Designtime.Metadata.Area area = Designtime.Metadata.SolutionHelper.GetArea(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.Name);
                            CurrentDesignMetadata4Scene.RemoveArea(area);
                        }
                        else if (part.ParentPart is Coolzon.UI.AreaPart)
                        {
                            Designtime.Metadata.Area dt_area = Designtime.Metadata.SolutionHelper.GetArea(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.ParentPart.Name);
                            if (part is Coolzon.UI.AreaPart)
                            {
                                Designtime.Metadata.Area dt_subArea = Designtime.Metadata.SolutionHelper.GetArea(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.Name);
                                dt_area.RemovePart(dt_subArea);
                            }
                            else
                            {
                                Designtime.Metadata.Part dt_subPart = Designtime.Metadata.SolutionHelper.GetPart(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.Name);
                                dt_area.RemovePart(dt_subPart);
                            }
                        }
                        else
                        {
                            Designtime.Metadata.Part dt_part = Designtime.Metadata.SolutionHelper.GetPart(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.ParentPart.Name);
                            Designtime.Metadata.Part dt_subPart = Designtime.Metadata.SolutionHelper.GetPart(UIContext.Current.CurrentSolution, CurrentDesignMetadata4Scene.Name, part.Name);
                            dt_part.RemovePart(dt_subPart);
                        }

                        _RaiseRemovedEvent(part);
                        if (this.SelectedChanged != null)
                        {
                            this.SelectedChanged(part.ParentPart);
                        }
                        _selectedPart = part.ParentPart;

                        if (this._selectedPart != null)
                        {
                            //更新mask的位置
                            ShowDesignBorder(_selectedPart, _ctlCanvas);

                            //保存设计边框的当前位置大小信息
                            this._dbPosStore = this._ctlDesignBorder.GetOffset();
                            this._dbSizeStore = this._ctlDesignBorder.GetSize();
                        }
                    }
                    else
                    {
                        Logger.WarningToTag(Library.LogTAG, "删除组件失败，组件parent为null");
                    }
                }
                else
                {
                    Logger.WarningToTag(Library.LogTAG, "删除组件失败，组件为null");
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag(Library.LogTAG, "删除组件失败,ex:{0}", ex);
            }
        }

        /// <summary>
        /// 添加组件
        /// </summary>
        /// <param name="newPart"></param>
        /// <param name="containerPart"></param>
        /// <param name="position"></param>
        /// <param name="size"></param>
        /// <param name="shortType"></param>
        /// <param name="DT_MetadataForRemoved"></param>
        public void API_AddPart(Coolzon.UI.Part newPart, Coolzon.UI.IPartContainer containerPart, Point position, Size size, string shortType, Designtime.Metadata.NodeBase DT_MetadataForRemoved = null)
        {
            _AddPartAndUpdateMetadata(newPart, containerPart, position, size, shortType, DT_MetadataForRemoved);
            // 通知有组件被创建
            _RaiseAddedEvent(newPart);

            _designData.UpdateState(DesignState.Normal);
            _ctlCanvas.Cursor = Cursors.Arrow;

            if (this.SelectedChanged != null)
            {
                this.SelectedChanged(newPart);
            }
            _selectedPart = newPart;

            if (this._selectedPart != null)
            {
                //更新mask的位置
                ShowDesignBorder(_selectedPart, _ctlCanvas);

                //保存设计边框的当前位置大小信息
                this._dbPosStore = this._ctlDesignBorder.GetOffset();
                this._dbSizeStore = this._ctlDesignBorder.GetSize();
            }
        }

        /// <summary>
        /// 关闭场景
        /// </summary>
        public void API_Reset()
        {
            this.Dispatcher.Invoke(() =>
            {
                if (CurrentScene != null)
                {
                    if (this._selectedPart != null && this.SelectedChanged != null)
                    {
                        this.SelectedChanged(null);
                    }
                    this._selectedPart = null;
                    CurrentDesignMetadata4Scene = null;
                    UIContext.Current.CurrentScene = null;
                    UIContext.Current.CurrentEditedNode = null;
                    CurrentScene = null;
                    scene = null;
                    _ctlDesignBorder.Visibility = System.Windows.Visibility.Hidden;
                    _ctlCanvas.Cursor = Cursors.Arrow;
                    _designData.UpdateState(DesignState.Normal);
                    Event.UI.UIEventBus.Publish(new Event.UI.UIToolboxSelectPointerEvent());
                    this._isEditable = false;
                    if (Closed != null)
                    {
                        Closed(_ctlMainFrame.CurrentScene);
                    }

                    _ctlMainFrame.ShowPart(null, CPPEI.Coolzon.UI.SwitchAnimationFactory.Create("None"));
                    _ctlMainFrame.Active(null, false, null);
                }
            });
        }

        /// <summary>
        /// 缩放至全部显示
        /// </summary>
        public void API_ZoomToShowAll()
        {
            double selZoomValue, heightZoomValue,widthZoomValue;
            heightZoomValue = (_ctlMainFrame.ActualHeight - 5) / _ctlMainFrame.CurrentScene.XHeight;
            widthZoomValue = (_ctlMainFrame.ActualWidth - 5) / _ctlMainFrame.CurrentScene.XWidth;
            selZoomValue = heightZoomValue > widthZoomValue ? widthZoomValue : heightZoomValue;

            this._ctlMainFrame.API_Zoom(selZoomValue, new Point(this._ctlMainFrame.ActualWidth / 2, this._ctlMainFrame.ActualHeight / 2));
        }

        /// <summary>
        /// 缩放是正常大小
        /// </summary>
        public void API_ZoomToNormal()
        {
            this._ctlMainFrame.API_Zoom(1, new Point(this._ctlMainFrame.ActualWidth / 2, this._ctlMainFrame.ActualHeight / 2));
        }

        /// <summary>
        /// 设置网格线类型
        /// </summary>
        /// <param name="gridLineType"></param>
        public void API_ChangeGridLineType(GridLineType gridLineType)
        {
            switch (gridLineType)
            {
                case GridLineType.x0:
                    _ctlCanvas.Background = Resources["_gridLine0"] as SolidColorBrush;
                    break;
                case GridLineType.x5:
                    _ctlCanvas.Background = Resources["_gridLine5"] as ImageBrush;
                    break;
                case GridLineType.x10:
                    _ctlCanvas.Background = Resources["_gridLine10"] as ImageBrush;
                    break;
                case GridLineType.x50:
                    _ctlCanvas.Background = Resources["_gridLine50"] as ImageBrush;
                    break;
                case GridLineType.x100:
                    _ctlCanvas.Background = Resources["_gridLine100"] as ImageBrush;
                    break;
            }
        }
    }

    public enum PasteType
    {
        None,
        Cut,
        Copy,
    }
}
